﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

// Overworld.cs
// Contains information about the overworld, such as a list of Sites to 
// enter, and the background.
namespace RTS_RPG
{
    public class Overworld
    {
        // Overworld's Fields
        public Overworld_Loader loader;
        public GameMap backDrop;
        public PlayerStats pstats;
        public Vector2 player_location;
        public float player_direction;
        public Vector2 world_size;
        public Overworld_TextureManager textures;
        public List<Site> places;
        public List<Overworld_Creature> creatures;
        public Vector2 open_creature_position;
        public Battle currentBattle;
        public Site currentSite;
        public GraphicsDeviceManager graphics;
        public ContentManager pause_screen_content;
        public ContentManager content;
        public IServiceProvider services;
        public PauseMenu pause_menu;
        public Boolean in_battle = false;
        public Boolean pause_screen = false;    // indicates a paused game, when the game is paused, update 
                                                // path stops here(at overworld) and calls pause menu update.
        // Constructor
        public Overworld(GameMap _backdrop, PlayerStats _pstats,
            GraphicsDeviceManager g, GameServiceContainer c)
        {
            services = c;
            pstats = _pstats;
            textures = new Overworld_TextureManager(services);

            backDrop = _backdrop;
            currentBattle = null;
            currentSite = null;
            graphics = g;
            content = new ContentManager(c);
            pause_menu = new PauseMenu(this, pstats);
            player_location = new Vector2(50, 50);
            player_direction = 0.0f;
            world_size = new Vector2(Program.SCREENWIDTH, Program.SCREENHEIGHT);

            textures.LoadOverworldContent();
            loader = new Overworld_Loader("test_world", textures, pstats);
            places = loader.find_overworld_sites(services);
            creatures = loader.find_overworld_creatures(open_creature_position);

            open_creature_position = new Vector2(700, 250);
        }

        public void update(GameTime gameTime, MouseState mstate, KeyboardState kstate)
        {
            if (kstate.IsKeyDown(Keys.P))
            {
                pause_screen = true;
                pause_screen_content = new ContentManager(services);
                textures.LoadPauseMenuContent();
            }
            if (pause_screen) 
            {
                pause_menu.update(gameTime, mstate, kstate);
                return;
            }
            if (currentBattle != null)
            {
                currentBattle.Update(gameTime, mstate, kstate);
                if (currentBattle.battle_over)
                {
                    textures.LoadOverworldContent();
                    creatures = loader.find_overworld_creatures(open_creature_position);
                    places = loader.find_overworld_sites(services);
                    currentBattle = null;
                }
            }
            else if (currentSite != null)
            {
                if (currentSite.update(mstate, kstate))
                    currentSite = null;
            }
            else update_map(mstate, kstate);
        }

        public void draw(GameTime gameTime, GraphicsDevice graphics_dev, SpriteBatch spBatch)
        {
            if (pause_screen)
            {
                pause_menu.draw(gameTime, graphics_dev, spBatch);
                return;
            }
            else if (currentBattle != null) currentBattle.Draw(gameTime, graphics_dev, spBatch);
            else if (currentSite != null) currentSite.draw_area(spBatch, graphics_dev);
            else
            {
                graphics_dev.Clear(Color.BurlyWood);
                /*spBatch.Draw(pstats.overworld_representation, 
                    new Vector2(player_location.X - (Overworld_TextureManager.HALF_CHARACTER_SIZE), 
                        player_location.Y - (Overworld_TextureManager.HALF_CHARACTER_SIZE)),
                        Color.White);*/

                spBatch.Draw(pstats.overworld_representation, player_location, null, Color.White, player_direction,
                    new Vector2(Overworld_TextureManager.HALF_CHARACTER_SIZE, Overworld_TextureManager.HALF_CHARACTER_SIZE), 
                    1.0f, new SpriteEffects(), 0);

                //pstats.party[0].draw(spBatch, player_location);
                foreach (Overworld_Creature creature in creatures) creature.draw(spBatch);
                foreach (Site site in places) site.draw(spBatch);
            }
        }

        private void update_map(MouseState mstate, KeyboardState kstate)
        {
            if (in_battle)
            {
                in_battle = false;
                //textures.LoadOverworldContent();  - moved to update method
            }
            if (kstate.IsKeyDown(Keys.Space))
            {
                // splashScreen = false;
                // battle_mode = true;
                currentBattle = new Battle(graphics, pstats, services);
                textures.UnloadOverworldContent();
                in_battle = true;
                return;
            }
            /*if (kstate.IsKeyDown(Keys.Down) && player_location.Y <= world_size.Y - 10)
                player_location.Y += 3;
            if (kstate.IsKeyDown(Keys.Up) && player_location.Y >= 10)
                player_location.Y -= 3;
            if (kstate.IsKeyDown(Keys.Right) && player_location.X <= world_size.X - 10)
                player_location.X += 3;
            if (kstate.IsKeyDown(Keys.Left) && player_location.X >= 10)
                player_location.X -= 3;*/

            determine_player_movement(kstate);

            foreach (Site site in places)
            {
                if (site.check_entry(this, null))
                {
                    currentSite = site;
                    return;
                }
            }

            for (int i = 0; i < creatures.Count; ++i)
            {
                creatures[i].update();
                if (Vector2.Distance(player_location, creatures[i].location) < 
                    (Overworld_TextureManager.HALF_CHARACTER_SIZE) + (creatures[i].enemy_party[0].representation.Width / 2) - 4)
                {
                    currentBattle = new Battle(graphics, pstats, services, creatures[i]);
                    textures.UnloadOverworldContent();
                    in_battle = true;
                    //Vector2 temp = open_creature_position;
                    open_creature_position = creatures[i].center_location;
                    /*creatures[i] = new Overworld_Creature(creatures[i].level, temp, creatures[i].movement_distance, 
                        creatures[i].vertical, pstats.textures);*/
                }
            }
        }

        private void determine_player_movement(KeyboardState kstate)
        {
            if (kstate.IsKeyDown(Keys.Down))
            {
                if (player_location.Y <= world_size.Y - 10) 
                    player_location.Y += 3;
                player_direction = (float)(0.5 * Math.PI);
            }
            if (kstate.IsKeyDown(Keys.Up))
            {
                if (player_location.Y >= 10) 
                    player_location.Y -= 3;
                player_direction = (float)(1.5 * Math.PI);
            }
            if (kstate.IsKeyDown(Keys.Right))
            {
                if (player_location.X <= world_size.X - 10)
                    player_location.X += 3;
                if (kstate.IsKeyDown(Keys.Down))
                    player_direction = (float)(0.25 * Math.PI);
                else if (kstate.IsKeyDown(Keys.Up))
                    player_direction = (float)(1.75 * Math.PI);
                else
                    player_direction = 0.0f;
            }
            if (kstate.IsKeyDown(Keys.Left))
            {
                if (player_location.X >= 10)
                    player_location.X -= 3;
                if (kstate.IsKeyDown(Keys.Down))
                    player_direction = (float)(0.75 * Math.PI);
                else if (kstate.IsKeyDown(Keys.Up))
                    player_direction = (float)(1.25 * Math.PI);
                else
                    player_direction = (float)(1.0 * Math.PI);
            }
        }
    }
}
